"""
枚举相关的数据模型
对应数据库表: base_enum_type, base_enum_item
"""
import json
from datetime import datetime
from typing import Optional, Dict, Any

from pydantic import BaseModel, Field, validator, ConfigDict


class EnumTypeBase(BaseModel):
    """
    枚举类型基础模型
    """
    type: str = Field(..., description="枚举类型标识，如DeviceType、AlarmType等", max_length=32)
    description: Optional[str] = Field(None, description="枚举类型描述", max_length=128)

    @validator('type')
    def validate_type_format(cls, v):
        """验证枚举类型格式"""
        if not v or not v.strip():
            raise ValueError("枚举类型不能为空")
        if not v.replace('_', '').replace('-', '').isalnum():
            raise ValueError("枚举类型只能包含字母、数字、下划线和连字符")
        return v.strip()


class EnumType(EnumTypeBase):
    """
    枚举类型完整模型（包含数据库字段）
    """
    id: int = Field(..., description="主键ID")

    model_config = ConfigDict(from_attributes=True)


class EnumItemBase(BaseModel):
    """
    枚举条目基础模型
    """
    type: str = Field(..., description="枚举类型", max_length=32)
    value: str = Field(..., description="枚举值", max_length=32)
    label: str = Field(..., description="枚举显示名", max_length=64)
    sort_order: int = Field(0, description="排序序号", ge=0, le=255)
    status: int = Field(1, description="状态：1启用，0禁用", ge=0, le=1)
    ext_json: Optional[Dict[str, Any]] = Field(None, description="扩展字段JSON")

    @validator('value')
    def validate_value_format(cls, v):
        """验证枚举值格式"""
        if not v or not v.strip():
            raise ValueError("枚举值不能为空")
        return v.strip()

    @validator('label')
    def validate_label_format(cls, v):
        """验证显示名格式"""
        if not v or not v.strip():
            raise ValueError("显示名不能为空")
        return v.strip()

    @validator('ext_json', pre=True)
    def validate_ext_json(cls, v):
        """验证扩展JSON字段"""
        if v is None:
            return v
        if isinstance(v, str):
            try:
                return json.loads(v)
            except json.JSONDecodeError:
                raise ValueError("扩展字段必须是有效的JSON格式")
        return v


class EnumItem(EnumItemBase):
    """
    枚举条目完整模型（包含数据库字段）
    """
    id: int = Field(..., description="主键ID")
    type_id: int = Field(..., description="枚举类型ID")
    gmt_create: datetime = Field(..., description="创建时间")

    model_config = ConfigDict(from_attributes=True)


class EnumItemWithType(EnumItem):
    """
    包含类型信息的枚举条目模型
    用于关联查询时返回
    """
    type_description: Optional[str] = Field(None, description="枚举类型描述")


class EnumGroup(BaseModel):
    """
    枚举分组模型
    用于批量返回某个类型下的所有枚举条目
    """
    type: str = Field(..., description="枚举类型")
    description: Optional[str] = Field(None, description="类型描述")
    items: list[EnumItem] = Field(default_factory=list, description="枚举条目列表")

    model_config = ConfigDict(from_attributes=True)


class EnumMap(BaseModel):
    """
    枚举映射模型
    用于前端下拉框等场景的数据结构
    """
    value: str = Field(..., description="枚举值")
    label: str = Field(..., description="显示名")
    disabled: bool = Field(False, description="是否禁用")
    ext: Optional[Dict[str, Any]] = Field(None, description="扩展字段")

    @classmethod
    def from_enum_item(cls, item: EnumItem) -> "EnumMap":
        """从枚举条目转换为映射模型"""
        return cls(
            value=item.value,
            label=item.label,
            disabled=item.status == 0,
            ext=item.ext_json
        )
